﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using SoftwareConsulting.BI11.Studio.Core.Project.SituationsHierarchy;
using SoftwareConsulting.BI11.Studio.BasicEntities;

namespace SoftwareConsulting.BI11.Studio.UI.ProjectExplorer.SituationsHierarchy
{
    /// <summary>
    /// Класс линии связи между ситуациями
    /// </summary>
    public sealed class LinkLine: UniqueChild
    {
        #region внутренние переменные
        private Guid _relatedLinkId; //идентификатор связи между ситуациями
        private Point _sourcePoint; //точка-источник
        private Point _destinationPoint; //точка-приёмник        
        private SituationsArea _area; //связь с областью ситуаций
        #endregion

        #region публичные свойства
        /// <summary>
        /// Возвращает/устанавливает родительскую область ситуаций
        /// </summary>
        public override Interfaces.BasicEntities.IUnique Parent
        {
            get
            {
                return base.Parent;
            }
            set
            {
                base.Parent = value;
                _area = value as SituationsArea;
            }
        }

        /// <summary>
        /// Геттер-сеттер точки-источника
        /// </summary>
        public Point SourcePoint
        {
            get
            {
                return _sourcePoint;
            }
            set
            {
                _sourcePoint = value;
            }
        }

        /// <summary>
        /// Геттер-сеттер точки-приёмника
        /// </summary>
        public Point DestinationPoint
        {
            get
            {
                return _destinationPoint;
            }
            set
            {
                _destinationPoint = value;
            }
        }

        /// <summary>
        /// Геттер идентификатора связи между ситуациями
        /// </summary>
        public Guid RelatedLinkId
        {
            get
            {
                return _relatedLinkId;
            }
        }
        #endregion

        #region публичные методы
        /// <summary>
        /// Определяет принадлежит ли точка линии
        /// </summary>
        /// <param name="point">проверяемая точка</param>
        /// <returns></returns>
        public bool IsPointOnLine(Point point)
        {            
            double Delta = 10; //допустимое отклонение от линии (в пикселях)            
            double eps = 0.0005;

            double X1 = SourcePoint.X;
            double Y1 = SourcePoint.Y;
            double X2 = DestinationPoint.X;
            double Y2 = DestinationPoint.Y;
                        
            double k_ = 0;            
            Point[] pts = new Point[4];
            byte[] types = new byte[4];
            if (Math.Abs(Y1-Y2)>=eps)
            {
                k_ = (X2-X1)/(Y1-Y2);                
            }            
            else
            {
                k_ = 1;                
            }
            double alpha=Math.Atan(k_);
            double betta=alpha;
            if (k_<0)
            {
                betta=Math.PI-alpha;
            }
            double cosbetta = Math.Cos(betta) * Delta;
            double sinbetta = Math.Sin(betta) * Delta;
            pts[0] = new Point((int)Math.Round(X1 - cosbetta), (int)Math.Round(Y1 + sinbetta));
            pts[1] = new Point((int)Math.Round(X1 + cosbetta), (int)Math.Round(Y1 - sinbetta));
            pts[2] = new Point((int)Math.Round(X2 + cosbetta), (int)Math.Round(Y2 - sinbetta));
            pts[3] = new Point((int)Math.Round(X2 - cosbetta), (int)Math.Round(Y2 + sinbetta));
            types[0] = (byte)PathPointType.Line;
            types[1] = (byte)PathPointType.Line;
            types[2] = (byte)PathPointType.Line;
            types[3] = (byte)PathPointType.Line;
            Region reg = new Region(new GraphicsPath(pts, types));
            return reg.IsVisible(point);
        }
        #endregion        

        #region конструкторы и финализаторы
        /// <summary>
        /// Конструктор класса
        /// </summary>
        public LinkLine(SituationsArea situationsArea, Link link, Point point1, Point point2) :
            base(situationsArea)
        {            
            _relatedLinkId = link.Id;
            _sourcePoint = point1;
            _destinationPoint = point2;
        }
        #endregion
    }
}
